from flask import (
    Blueprint, g, request, session, Response, stream_with_context
)

import json
import queue
import threading


bp = Blueprint('event', __name__, url_prefix='/event')

# 全局订阅者列表：每个订阅者是一个线程安全的 queue
_subscribers = []
_subscribers_lock = threading.Lock()


def broadcast_event(event):
    """
    广播事件给所有当前连接的客户端
    event: dict, 如 {'type': 'update-room'}
    """
    with _subscribers_lock:
        # 从列表副本遍历，避免在遍历时被修改
        for q in _subscribers[:]:
            try:
                q.put(event)
            except Exception as e:
                print("出现事件流订阅者异常")


@bp.route('/create-events')
def events():
    # 为每个客户端创建独立的消息队列
    client_queue = queue.Queue()

    # 加入全局订阅者列表
    with _subscribers_lock:
        _subscribers.append(client_queue)

    def event_stream():
        try:
            while True:
                try:
                    # 等待消息，30秒超时（防止连接被中间件断开）
                    event = client_queue.get(timeout=30)
                    yield f"data: {json.dumps(event)}\n\n"
                except queue.Empty:
                    # 发送心跳，保持连接
                    yield ":\n\n"
                    continue
        except GeneratorExit:
            # 客户端断开连接
            pass
        finally:
            # 清理：从订阅者中移除
            with _subscribers_lock:
                if client_queue in _subscribers:
                    _subscribers.remove(client_queue)

    return Response(
        stream_with_context(event_stream()),
        mimetype='text/event-stream',
        headers={
            'Cache-Control': 'no-cache',
            'Access-Control-Allow-Origin': '*',  # 跨域
            'Connection': 'keep-alive',
            'X-Accel-Buffering': 'no'  # Nginx: 禁用缓冲
        }
    )


# 更新房间
def update_room():
    broadcast_event({'type': 'update-room'})

# 同步信息
def tongbu(id):
    broadcast_event({'type': f'tongbu-{id}'})

# # 更新状态
# def update_status():
#     broadcast_event({'type': 'update-status'})

# # 更新游戏信息
# def update_game_id(id):
#     broadcast_event({'type': f'update-game-{id}'})
       
# def update_gamestatus_id(id):
#     broadcast_event({'type': f'update-gamestatus-{id}'})